use num_traits::FromPrimitive;

#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub(crate) enum SelectValue {
    String(String),
    Number(i64),
    Bool(bool),
}

impl From<String> for SelectValue {
    fn from(value: String) -> Self {
        Self::String(value)
    }
}
impl From<&str> for SelectValue {
    fn from(value: &str) -> Self {
        Self::String(value.to_string())
    }
}

impl From<u8> for SelectValue {
    fn from(value: u8) -> Self {
        Self::Number(value as i64)
    }
}
impl From<u16> for SelectValue {
    fn from(value: u16) -> Self {
        Self::Number(value as i64)
    }
}
impl From<u32> for SelectValue {
    fn from(value: u32) -> Self {
        Self::Number(value as i64)
    }
}
impl From<i8> for SelectValue {
    fn from(value: i8) -> Self {
        Self::Number(value as i64)
    }
}

impl From<i16> for SelectValue {
    fn from(value: i16) -> Self {
        Self::Number(value as i64)
    }
}
impl From<i32> for SelectValue {
    fn from(value: i32) -> Self {
        Self::Number(value as i64)
    }
}
impl From<i64> for SelectValue {
    fn from(value: i64) -> Self {
        Self::Number(value)
    }
}

impl From<bool> for SelectValue {
    fn from(value: bool) -> Self {
        Self::Bool(value)
    }
}

impl FromPrimitive for SelectValue {
    fn from_i64(n: i64) -> Option<Self> {
        Some(Self::Number(n))
    }

    fn from_u64(n: u64) -> Option<Self> {
        let max = i64::MAX as u64;
        if n > max {
            None
        } else {
            Some(Self::Number(n as i64))
        }
    }
}
